package com.example.videodemo;

import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;

import com.example.jna.HCNetSDKByJNA;
import com.example.jna.HCNetSDKJNAInstance;

import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.INT_PTR;
import com.hikvision.netsdk.NET_DVR_DIGITAL_CHANNEL_STATE;
import com.hikvision.netsdk.NET_DVR_IPCHANINFO;
import com.hikvision.netsdk.NET_DVR_IPPARACFG_V40;
import com.hikvision.netsdk.NET_DVR_JPEGPARA;
import com.hikvision.netsdk.NET_DVR_PICCFG_V30;
import com.hikvision.netsdk.NET_DVR_PRESET_NAME;
import com.hikvision.netsdk.NET_DVR_PRESET_NAME_ARRAY;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.hikvision.netsdk.NET_DVR_SETUPALARM_PARAM;

import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;

import static com.example.jna.HCNetSDKByJNA.BYTE_ARRAY_LEN;
import static com.example.jna.HCNetSDKByJNA.ISAPI_DATA_LEN;
import static com.example.jna.HCNetSDKByJNA.ISAPI_STATUS_LEN;
import static com.example.jna.HCNetSDKByJNA.NET_DVR_GET_PICCFG_V40;
import static com.hikvision.netsdk.HCNetSDK.DEVICE_VIDEOPIC_ABILITY;
import static com.hikvision.netsdk.HCNetSDK.NET_DVR_GET_DIGITAL_CHANNEL_STATE;
import static com.hikvision.netsdk.HCNetSDK.NET_DVR_GET_IPPARACFG_V40;
import static com.hikvision.netsdk.HCNetSDK.NET_DVR_GET_PICCFG_V30;
import static com.hikvision.netsdk.HCNetSDK.NET_DVR_GET_PRESET_NAME;


public class RcvModel {
    String TAG="RcvModel";
    DeviceItem devItem ;

    private static RcvModel rcvModel;
    public static RcvModel getInstance(){
        if (rcvModel==null){
            rcvModel=new RcvModel();
        }
        return rcvModel;
    }
    private RcvModel(){
        if(initSDK()!=0){
            Log.e(TAG,"初始化失败"+ HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
        };
    }
    //初始化SDK
    public int initSDK() {
        if (!HCNetSDK.getInstance().NET_DVR_Init()) {
            return HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError();
        }
        //设置JSON和图片分离
        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/", true);
        int dwType = HCNetSDKByJNA.NET_SDK_LOCAL_CFG_TYPE.NET_DVR_LOCAL_CFG_TYPE_GENERAL;
        HCNetSDKByJNA.NET_DVR_LOCAL_GENERAL_CFG struGeneralCfg = new HCNetSDKByJNA.NET_DVR_LOCAL_GENERAL_CFG();
        Pointer lpInBuff = struGeneralCfg.getPointer();
        struGeneralCfg.byAlarmJsonPictureSeparate = 1;
        struGeneralCfg.write();
        boolean bRet = HCNetSDKJNAInstance.getInstance().NET_DVR_SetSDKLocalCfg(dwType, lpInBuff);
        if (!bRet) {
            System.out.println("NET_DVR_SetSDKLocalCfg(NET_SDK_LOCAL_CFG_TYPE_CHECK_DEV) failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            return HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError();

        }
        return 0;

    }

    public int login(int pos, LiveData<List<RcvData>> listLiveData) {
        RcvData data = listLiveData.getValue().get(pos);
        HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO();
        System.arraycopy(data.getIp().getBytes(), 0, loginInfo.sDeviceAddress, 0, data.getIp().length());
        System.arraycopy(data.getUserName().getBytes(), 0, loginInfo.sUserName, 0, data.getUserName().length());
        System.arraycopy(data.getPassword().getBytes(), 0, loginInfo.sPassword, 0, data.getPassword().length());
        loginInfo.wPort = (short) Integer.parseInt(data.getPort());
        HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40();
        loginInfo.write();

        int iUserID = HCNetSDKJNAInstance.getInstance().NET_DVR_Login_V40(loginInfo.getPointer(), deviceInfo.getPointer());
        deviceInfo.read();

        devItem= new DeviceItem();
        devItem.m_byLoginFlag = 1;
        devItem.m_lUserID = iUserID;
        if (data.getName().isEmpty()){
            devItem.m_szDevName = data.getIp();
        }
        devItem.m_struDevState.m_iLogState = 1;
        devItem.m_rcvData = data;
        devItem.m_struDeviceInfoV40_jna = deviceInfo;

        return iUserID;
    }
    public DeviceItem login(RcvData data) {

        HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO();
        System.arraycopy(data.getIp().getBytes(), 0, loginInfo.sDeviceAddress, 0, data.getIp().length());
        System.arraycopy(data.getUserName().getBytes(), 0, loginInfo.sUserName, 0, data.getUserName().length());
        System.arraycopy(data.getPassword().getBytes(), 0, loginInfo.sPassword, 0, data.getPassword().length());
        loginInfo.wPort = (short) Integer.parseInt(data.getPort());
        HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40();
        loginInfo.write();

        int iUserID = HCNetSDKJNAInstance.getInstance().NET_DVR_Login_V40(loginInfo.getPointer(), deviceInfo.getPointer());
        Log.e(TAG, "login: "+iUserID );
        if(iUserID==-1){
            int err=HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError();
            Log.e(TAG, "login: "+err );
        }

        deviceInfo.read();

        devItem= new DeviceItem();
        devItem.m_byLoginFlag = 1;
        devItem.m_lUserID = iUserID;
        if (data.getName().isEmpty()){
            devItem.m_szDevName = data.getIp();
        }
        devItem.m_struDevState.m_iLogState = 1;
        devItem.m_rcvData = data;
        devItem.m_struDeviceInfoV40_jna = deviceInfo;

        return devItem;
    }

    public List getRcvChanel(){
        NET_DVR_DIGITAL_CHANNEL_STATE channel_state= new NET_DVR_DIGITAL_CHANNEL_STATE();

        boolean f=HCNetSDK .getInstance().NET_DVR_GetDVRConfig(devItem.m_lUserID,NET_DVR_GET_DIGITAL_CHANNEL_STATE,0,channel_state);
        if(!f){
            return null;
        }
        int byChanNum = devItem.m_struDeviceInfoV40_jna.struDeviceV30.byIPChanNum;
        int byStartChan = devItem.m_struDeviceInfoV40_jna.struDeviceV30.byStartDChan;
        byte[] chanState = channel_state.byDigitalChanState;
        List<RcvJpg>list =new ArrayList<>();

        NET_DVR_JPEGPARA net_dvr_jpegpara = new NET_DVR_JPEGPARA();
        net_dvr_jpegpara.wPicQuality=0;
        net_dvr_jpegpara.wPicSize=2;
        for (int i = 0; i<byChanNum;i++){
            if(chanState[i]==1){
                byte[] bytes = new byte[352*288];
                INT_PTR int_ptr = new INT_PTR();
                boolean b=HCNetSDK.getInstance().NET_DVR_CaptureJPEGPicture_NEW(devItem.m_lUserID,byStartChan+i,net_dvr_jpegpara,bytes,bytes.length,int_ptr);
                if(!b){
                    Log.e(TAG,"ERROR:++"+HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
                }
                HCNetSDKByJNA.NET_DVR_PICCFG_V40 netDvrPiccfgV30 =new HCNetSDKByJNA.NET_DVR_PICCFG_V40();
                IntByReference intByReference =new IntByReference();
                int size = netDvrPiccfgV30.size();
                String cn=null;
                boolean bf=HCNetSDKJNAInstance .getInstance().NET_DVR_GetDVRConfig(devItem.m_lUserID,NET_DVR_GET_PICCFG_V40,byStartChan+i,netDvrPiccfgV30.getPointer(),size,intByReference);
                if(!bf){
                    Log.e(TAG,"ERROR:++"+HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
                }else {
                    netDvrPiccfgV30.read();
                    byte[] chanNames = netDvrPiccfgV30.sChanName;

                    try {
                        String chanName =new String(chanNames,"GBK");
                        cn=chanName;
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }

                }
                list.add( new RcvJpg(byStartChan+i,bytes,cn));
            }
        }




        return list;
    }
    public int startPlay(SurfaceView m_osurfaceView, int iPreviewID,int Chanel) {
        if (iPreviewID != -1) {
            RealPlay_Stop(iPreviewID);
        }

        NET_DVR_PREVIEWINFO struPlayInfo = new NET_DVR_PREVIEWINFO();
        struPlayInfo.lChannel = Chanel;
        struPlayInfo.dwStreamType = 1;
        struPlayInfo.bBlocked = 1;
        struPlayInfo.hHwnd = m_osurfaceView.getHolder();
        int iUserID=devItem.m_lUserID;
        if (iUserID < 0) {
            Log.e("SimpleDemo", "RealPlay_V40_jni failed with error param");
            iPreviewID= -1;
        }else {
            iPreviewID = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(iUserID, struPlayInfo, null);
            if(iPreviewID < 0)
            {
                INT_PTR int_ptr = new INT_PTR();
                Log.e(TAG, "startPlay: "+ HCNetSDK.getInstance().NET_DVR_GetErrorMsg(int_ptr));
                int iValue = int_ptr.iValue;
                iPreviewID= -1;
            }
        }

        //播放声音
//        boolean bRet = HCNetSDKJNAInstance.getInstance().NET_DVR_OpenSound((short)iRet);
//        if(bRet){
//            Log.e("", "NET_DVR_OpenSound Succ!");
//        }


        return iPreviewID;


    }

    public boolean RealPlay_Stop(int iPreviewID) {
        if (iPreviewID < 0) {
            Log.e("SimpleDemo", "RealPlay_Stop_jni failed with error param");
            return false;
        }
        if(!HCNetSDK.getInstance().NET_DVR_StopRealPlay(iPreviewID))
        {
            Log.e("SimpleDemo", "RealPlay_Stop_jni failed");
            return false;
        }
        return true;
    }





    public int RealPlaySurfaceChanged_jni(int iPreviewID, int i, SurfaceHolder holder) {
        if (iPreviewID < 0 || i < 0) {
            Log.e("SimpleDemo", "RealPlaySurfaceChanged_jni failed with error param");
            return -1;
        }
        return  HCNetSDK.getInstance().NET_DVR_RealPlaySurfaceChanged(iPreviewID, i, holder);
    }

    public void logout(int iUserID) {

        boolean ret = HCNetSDK.getInstance().NET_DVR_Logout_V30(iUserID);
        if (!ret){
            Log.e("[NetSDKSimpleDemo]","NET_DVR_Logout failed with:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
        }

//        alarmliveData.postValue(info1);
        devItem.m_struDevState.reset();
        devItem.m_struDeviceInfoV30_jni = null;
        devItem.m_struDeviceInfoV40_jna = null;;
    }









}
